#include "datamanager.h"
#include <QDir>
#include <osgDB\Registry>
#include <osgDB\ReadFile>
#include "utility.h"
#include "layersmanager.h"
#include "actorbase.h"
#include <QFile>
#include <QFileInfo>
#include <CompressFolder.h>
#include "actorfactory.h"
#include "deviceactor.h"
#include <osgDB\DynamicLibrary>
#include "allactorfactory.h"
#include "resourceloader.h"
#include "datatypedefine.h"
#include "configfileoperation.h"
#include "lightsourcemanager.h"

VrDataCore::DataManager* VrDataCore::DataManager::_datamanager = NULL;

namespace VrDataCore
{
	DataManager::DataManager():_currentMap(NULL),_sourceLoadDirectory("")
	{
		_actorFactory = new AllActorFactory;
		_mapXMLRW = new MapReadWriteXml(_actorFactory);
	}

	DataManager::~DataManager()
	{
		delete _actorFactory;
		_actorFactory = NULL;
	}

	DataManager& DataManager::GetInstance()
	{
		if(_datamanager == NULL)
			_datamanager = new DataManager;
		return *_datamanager;
	}

	CoreBase::ActorFactory* DataManager::getActorFactory()
	{
		return _actorFactory;
	}

	void DataManager::clearData()
	{
		LayersManager::GetInstance().setCurrentMap(NULL);
		_deviceNameToResourceActor.clear();
		_deviceTypeToResourceActor.clear();
		for(QMap<QString,osg::ref_ptr<osg::StateSet>>::iterator iter = _drawableNameToStateSet.begin();
			iter!=_drawableNameToStateSet.end();++iter)
		{
			iter.value()->releaseGLObjects();
		}
		_drawableNameToStateSet.clear();
		//_filenameToImageCache.clear();
		//for(QMap<QString,osg::ref_ptr<osg::Texture2D>>::iterator iter = _filenameToTexture2DCache.begin();
		//	iter!=_filenameToTexture2DCache.end();++iter)
		//{
		//	iter.value()->releaseGLObjects();
		//}
		//_filenameToTexture2DCache.clear();
		_allResourceMap.clear();
		_currentMap = NULL;
		CoreBase::ResourceLoader::GetInstance().flushObjectCache();
	}

	void DataManager::newMap()
	{
		_currentMap = new CoreBase::Map(MAP_TYPE_MAINMAP);
		LayersManager::GetInstance().createEnvironmentLayer(_currentMap);
		LayersManager::GetInstance().createNoEnvironmentLayer(_currentMap);
		LayersManager::GetInstance().createGuideMapActor(_currentMap);
		LayersManager::GetInstance().setCurrentMap(_currentMap);
		LightSourceManager::GetInstance().setCurrentMap(_currentMap);
		LightSourceManager::GetInstance().initDefaultLightSource();
		_currentMapFileName = "";
	}

	void DataManager::openMap(const QString& mapfullname)
	{
		_currentMap = new CoreBase::Map(MAP_TYPE_MAINMAP);
		_mapXMLRW->openXMLFile(mapfullname,_currentMap);
		_currentMapFileName = mapfullname;
		//load resource
		QStringList list = _currentMap->getAllResource();
		for(int i=0;i<list.size();++i)
		{
			loadResource(list.at(i));
		}
		//replace
		openMapEnd(_currentMap);
		//relink
		LayersManager::GetInstance().setCurrentMap(_currentMap);
		LightSourceManager::GetInstance().setCurrentMap(_currentMap);
	}

	void DataManager::clostMap()
	{
		clearData();
		_currentMapFileName = "";
	}

	void DataManager::saveMap()
	{
		if (_currentMap.valid())
		{
			saveCurrentMapResource(_currentMap,_allResourceMap);
			_mapXMLRW->saveXMLFile(_currentMapFileName,_currentMap);
			//save resource
			saveAllResourceToFile();
		}
	}

	void DataManager::saveAsMap(const QString& mapfullname)
	{
		_currentMapFileName = mapfullname;
		if (_currentMap.valid())
		{
			saveCurrentMapResource(_currentMap,_allResourceMap);
			_mapXMLRW->saveXMLFile(_currentMapFileName,_currentMap);
			//save resource
			saveAllResourceToFile();
		}
	}

	void DataManager::saveCurrentMapResource(CoreBase::Map* curmap,const QMap<QString,osg::ref_ptr<CoreBase::Map>>& resourcemaps)
	{
		QMap<QString,osg::ref_ptr<CoreBase::Map>>::Iterator iter = resourcemaps.begin();
		for(;iter!=resourcemaps.end();++iter)
		{
			curmap->addResource(iter.key());
		}
	}

	CoreBase::Map* DataManager::getCurrentMap()
	{
		return _currentMap.get();
	}

	bool DataManager::currentMapContains(CoreBase::ActorBase* actor)
	{
		QMap<QString,osg::ref_ptr<CoreBase::Map>>::iterator iter = _allResourceMap.begin();
		for(;iter!=_allResourceMap.end();++iter)
		{
			CoreBase::ActorBase* getactor = iter.value()->getActorById(actor->getId());
			if(getactor!=NULL)
			{
				return false;
			}
		}
		return true;
	}

	bool DataManager::mapIsModified()
	{
		if(_currentMap.valid())
		{
			return _currentMap->isModified();
		}
		return false;
	}

	void DataManager::openMapEnd(CoreBase::Map* curmap)
	{
		QMap<CoreBase::ActorBase*,osg::ref_ptr<CoreBase::ActorBase>> oldtonew;
		QMap<QString,osg::ref_ptr<CoreBase::ActorBase>> allactors = curmap->getAllActors();
		QMap<QString,osg::ref_ptr<CoreBase::ActorBase>>::iterator iter = allactors.begin();
		for(;iter!=allactors.end();++iter)
		{
			if(iter.value()->isInstanceOf(CLASS_DEVICE))
			{
				QString id = iter.value()->getId();
				//new device
				osg::ref_ptr<CoreBase::ActorBase> getactor = getResourceActorByName(iter.value()->getName());
				if(getactor.valid())
				{
					osg::ref_ptr<CoreBase::ActorBase> newdevice = getactor->clone();
					newdevice->setId(id);
					newdevice->copyPropertiesFrom(*iter.value().get());
					oldtonew.insert(iter.value().get(),newdevice);
				}
			}			
		}
		QMap<CoreBase::ActorBase*,osg::ref_ptr<CoreBase::ActorBase>>::Iterator updateiter = oldtonew.begin();
		for(;updateiter!=oldtonew.end();++updateiter)
		{
			curmap->removeActor(*updateiter.key());
			curmap->addActor(*updateiter.value());
		}
	}

	void DataManager::setApplicationDir(const QString& dirstring)
	{
		_applicationDirString = dirstring;
	}

	QString DataManager::getApplicationDir()
	{
		return _applicationDirString;
	}

	void DataManager::createWorkPath(const QString& workpath)
	{
		QDir dir;
		dir.setPath(workpath + "/maps");
		if (!dir.exists())
		{
			bool bmade = dir.mkpath(workpath + "/maps");
		}
		dir.setPath(workpath + "/meshes");
		if (!dir.exists())
		{
			bool bmade = dir.mkpath(workpath + "/meshes");
		}
		dir.setPath(workpath + "/meshes" + GRASSMODELDIR);
		if (!dir.exists())
		{
			bool bmade = dir.mkpath(workpath + "/meshes" + GRASSMODELDIR);
		}
		dir.setPath(workpath + "/meshes" + TREEMODELDIR);
		if (!dir.exists())
		{
			bool bmade = dir.mkpath(workpath + "/meshes" + TREEMODELDIR);
		}
		dir.setPath(workpath + "/scenetextures");
		if (!dir.exists())
		{
			bool bmade = dir.mkpath(workpath + "/scenetextures");
		}
	}

	bool DataManager::configSceneContextFilePath()
	{
	//	osgDB::DynamicLibrary* test = osgDB::DynamicLibrary::loadLibrary(
	//		ChineseTexttoStdstring(_applicationDirString)+"\\osgdb_ived.dll");
		//osgDB::DynamicLibrary::HANDLE ttt = test->getHandle();
		CoreBase::ConfigFileOperation::GetInstance().loadConfigFile(_applicationDirString);
		_workContextDir = _applicationDirString + CONTEXT_DIR;
		QString resourcecontex = _applicationDirString + RESOURCE;
		QString	guidefolder = _applicationDirString + GUIDE_IMAGE_FOLDER;
		_defaultSourceDirectory.push_back(_workContextDir);
		_defaultSourceDirectory.push_back(_workContextDir+"\\scenetextures");
		_defaultSourceDirectory.push_back(_workContextDir+"\\scenetextures\\skydome");
		_defaultSourceDirectory.push_back(_workContextDir+"\\scenetextures\\billboard");
		_defaultSourceDirectory.push_back(guidefolder);
		CoreBase::ResourceLoader::GetInstance().setDefaultSourceDirectory(_defaultSourceDirectory);
		for(int i=0;i<_defaultSourceDirectory.size();++i)
		{
			osgDB::Registry::instance()->getDataFilePathList().push_back(ChineseTexttoStdstring(_defaultSourceDirectory.at(i)));
		}
		QDir dir(_workContextDir);
		if(!dir.exists())
		{
			bool bmade = dir.mkpath(_workContextDir);		
		}
		dir.setPath(resourcecontex);
		if(!dir.exists())
		{
			bool bmade = dir.mkpath(resourcecontex);
		}
		dir.setPath(guidefolder);
		if(!dir.exists())
		{
			bool bmade = dir.mkpath(resourcecontex);
		}
		createWorkPath(_workContextDir);
		return true;
	}

	QString DataManager::getResourceContextByMap(CoreBase::Map* resourcemap)
	{
		QMap<QString,osg::ref_ptr<CoreBase::Map>>::Iterator iter = _allResourceMap.begin();
		for(;iter!=_allResourceMap.end();++iter)
		{
			if(iter.value().get() == resourcemap)
				return _workContextDir+"\\meshes\\"+ iter.key();
		}
		return "";
	}

	void DataManager::copyFolder(QDir& oldFolder,QDir& newFolder)
	{
		QFileInfoList list = oldFolder.entryInfoList();
		for (int i = 0; i < list.size(); ++i) 
		{
			QFileInfo fileInfo = list.at(i);
			if ((fileInfo.fileName() != ".") && (fileInfo.fileName()!="..")) 
			{
				if(fileInfo.isDir())
				{ 
					oldFolder.setPath(oldFolder.path()+"/"+fileInfo.fileName()) ;
					newFolder.mkpath(newFolder.path()+"/"+fileInfo.fileName());
					newFolder.setPath(newFolder.path()+"/"+fileInfo.fileName());
					copyFolder(oldFolder,newFolder);
					oldFolder.cdUp();
					newFolder.cdUp();
				}
				else
				{
					QString mextension = fileInfo.absoluteFilePath().mid(fileInfo.absoluteFilePath().lastIndexOf('.'),
										 fileInfo.absoluteFilePath().length()-fileInfo.absoluteFilePath().lastIndexOf('.'));
					QString s;                                
					s = oldFolder.relativeFilePath(fileInfo.absoluteFilePath());
					if(QFile::exists(newFolder.path()+"/"+s))
					{
						QFile::remove(newFolder.path()+"/"+s);
					}
					QFile::copy(fileInfo.absoluteFilePath(),newFolder.path()+"/"+s);
				}
			}
		}
	}

	void DataManager::deleteFolder(const QString& mpath) const
	{
		if(mpath.contains(":"))
		{
			QDir dir(mpath);
			QStringList mfolders = dir.entryList(QDir::AllDirs|QDir::NoDotAndDotDot,QDir::Name);
			QStringList m_allfiles = dir.entryList(QDir::Files|QDir::NoDotAndDotDot|QDir::Hidden,QDir::Name);
			for(int i=0;i<m_allfiles.size();++i)
			{
				QFile::remove(mpath + "/" +m_allfiles[i]);
			}
			for(int i=0;i<mfolders.size();++i)
			{
				deleteFolder(mpath + "/" +mfolders[i]);
			}
			dir.rmdir(mpath);
		}
	}

	void DataManager::deleteAllFileInFolder(const QString& mpath) const
	{
		QDir folderdir(mpath);
		QFileInfoList list = folderdir.entryInfoList();
		for (int i = 0; i < list.size(); ++i) 
		{
			QFileInfo fileInfo = list.at(i);
			if ((fileInfo.fileName() != ".") && (fileInfo.fileName()!="..")) 
			{
				if(fileInfo.isDir())
				{ 
					deleteFolder(folderdir.path()+"/"+fileInfo.fileName());
				}
				else
				{
					QFile::remove(folderdir.path()+"/"+fileInfo.fileName());
				}
			}
		}
	}

	void DataManager::deleteFilesInFolder(const QString& mpath,const QString& suffixstr,bool searchchild) const
	{
		QDir folderdir(mpath);
		QFileInfoList list = folderdir.entryInfoList();
		for (int i = 0; i < list.size(); ++i) 
		{
			QFileInfo fileInfo = list.at(i);
			if ((fileInfo.fileName() != ".") && (fileInfo.fileName()!="..")) 
			{
				if(fileInfo.isDir() && searchchild)
				{ 
					deleteFilesInFolder(folderdir.path()+"/"+fileInfo.fileName(),suffixstr,searchchild);
				}
				else
				{
					if(fileInfo.suffix() == suffixstr)
					{
						QFile::remove(folderdir.path()+"/"+fileInfo.fileName());
					}
				}
			}
		}
	}

	void DataManager::copyFileToFolder(const QStringList& filelist,const QString& todir,bool mcovered)
	{
		//bool m_notcovered = false;
		QDir dir(todir);
		if(!dir.exists())
		{
			dir.mkpath(todir);
		}
		int i = 0;
		while(i < filelist.count())
		{
			QString f = todir + "/" + QFileInfo(filelist[i]).fileName();
			if(QFile::exists(f))
			{
				if(mcovered)
				{
					QFile::remove(f);
					QFile::copy(filelist[i],todir + "/" + QFileInfo(filelist[i]).fileName());
				}
			}
			else
				QFile::copy(filelist[i],todir + "/" + QFileInfo(filelist[i]).fileName());
			i++;
		}
	}

	void DataManager::findAllFileByExtension(const QString& mpath,const QStringList extensionnamelist, QStringList * mreturnList)
	{
		QDir dir(mpath);
		QStringList mfolders = dir.entryList(QDir::AllDirs|QDir::NoDotAndDotDot,QDir::Name);
		QStringList m_allfiles = dir.entryList(QDir::Files|QDir::NoDotAndDotDot,QDir::Name);
		for(int i=0;i<m_allfiles.size();++i)
		{
			if(extensionnamelist.contains(m_allfiles[i].mid(m_allfiles[i].lastIndexOf('.'),m_allfiles[i].length()-m_allfiles[i].lastIndexOf('.')).toLower()))
			{
				mreturnList->push_back(mpath + "/" +m_allfiles[i]);
			}
		}
		for(int i=0;i<mfolders.size();++i)
		{
			findAllFileByExtension(mpath + "/" +mfolders[i],extensionnamelist,mreturnList);
		}
	}

	void DataManager::decompressionSceneSources(QString mpath)
	{
		std::string mcontext =  ChineseTexttoStdstring(_workContextDir+"\\meshes\\");
		QFileInfo mfile(mpath);
		std::vector<std::string> veceg;
		veceg.push_back("7za");
		veceg.push_back("x");
		veceg.push_back(ChineseTexttoStdstring(mpath));
		veceg.push_back("-o"+mcontext);
		ClassCompressDirectory exactproject;
		exactproject.CompressDirectory(4,veceg);
	}

	void DataManager::compressionFileTo(const QString& compressfile,const QString& to)
	{
		QFile::remove(to);
		QString mfilename = to.mid(0,to.lastIndexOf('.'));
		QFile::remove(mfilename+".7z");
		std::vector<std::string> veceg;
		veceg.push_back("7z");
		veceg.push_back("a");
		veceg.push_back("-t7z");
		veceg.push_back(ChineseTexttoStdstring(mfilename+".7z"));
		veceg.push_back(ChineseTexttoStdstring(compressfile));
		//veceg.push_back("-mx0");
		veceg.push_back("-m0=LZMA");// Copy
		ClassCompressDirectory  compresDirectory;
		compresDirectory.CompressDirectory(6,veceg);
		QFileInfo info(mfilename+".7z");
		QString filenameexcpath = info.fileName();
		QFile::rename(mfilename+".7z",to);
	}

	void DataManager::newResource(const QString& jcfilename)
	{
		QString filename = jcfilename.mid(0,jcfilename.lastIndexOf('.'));
		QString pathstr = _workContextDir+"\\meshes\\" + jcfilename;
		QDir newresourcedir(pathstr);
		if(newresourcedir.exists())
			deleteFolder(pathstr);
		newresourcedir.mkpath(pathstr);
		createWorkPath(pathstr);
		osg::ref_ptr<CoreBase::Map> newresourcemap = new CoreBase::Map(MAP_TYPE_RESOURCEMAP);
		_allResourceMap.insert(jcfilename,newresourcemap);
		_mapXMLRW->saveXMLFile(pathstr+"\\maps\\"+filename+".jcyj",newresourcemap.get());
	}

	void DataManager::renameResource(const QString& jcfilefloder,const QString& newname)
	{
		osg::ref_ptr<CoreBase::Map> map = _allResourceMap.value(jcfilefloder);
		getCurrentMap()->resourceRename(jcfilefloder,newname);
		_allResourceMap.remove(jcfilefloder);
		_allResourceMap.insert(newname,map);
		QString oldpathstr = _workContextDir+"\\meshes\\" + jcfilefloder;
		QString newpathstr = _workContextDir+"\\meshes\\" + newname;
		QDir dir(oldpathstr);
		dir.rename(oldpathstr,newpathstr);
		QStringList extensionnamelist;
		extensionnamelist<<".jcyj";
		QStringList mreturnList;
		findAllFileByExtension(newpathstr,extensionnamelist,&mreturnList);
		if(mreturnList.size()>0)
		{
			QString filenamewithpath = mreturnList.at(0);
			QFile::rename(filenamewithpath,filenamewithpath.replace(jcfilefloder,newname));
		}
	}

	void DataManager::loadResource(const QString& jcfile,bool finddefresource)
	{
		QString filename = jcfile.mid(0,jcfile.lastIndexOf('.'));
		QString pathstr = _workContextDir+"\\meshes\\" + jcfile + "\\maps\\" + filename + ".jcyj";
		if(QFile::exists(pathstr))
		{
			osg::ref_ptr<CoreBase::Map> resourcemap = new CoreBase::Map(MAP_TYPE_RESOURCEMAP);
			_mapXMLRW->openXMLFile(pathstr,resourcemap.get());
			onResourceMapLoadEnd(resourcemap.get());
			_allResourceMap.insert(jcfile,resourcemap);
		}
		else
		{
			if(finddefresource)
			{
				QString defresourcepath = _applicationDirString + RESOURCE;
				QString jcfilewithpath = "";
				if(_sourceLoadDirectory!="")
					jcfilewithpath = _sourceLoadDirectory+ "\\" + jcfile;
				else
					jcfilewithpath = defresourcepath + "\\" + jcfile;
				if(QFile::exists(jcfilewithpath))
				{
					decompressionSceneSources(jcfilewithpath);
					loadResource(jcfile,false);
				}
			}
		}
	}

	void DataManager::setSourceLoadDirectory(const QString& dir)
	{
		_sourceLoadDirectory = dir;
	}

	const QMap<QString,osg::ref_ptr<CoreBase::Map>>& DataManager::getAllResourceMap()
	{
		return _allResourceMap;
	}

	void DataManager::exportResourceAsJC(const QString& resourcename,const QString& filenamewithpath)
	{
		CoreBase::Map* resourcemap = getResourceMap(resourcename);
		QString mapfilewithpath = _workContextDir+"\\meshes\\" + resourcename+"\\maps\\";
		QString filename = resourcename.mid(0,resourcename.lastIndexOf('.'));
		_mapXMLRW->saveXMLFile(mapfilewithpath+filename+".jcyj",resourcemap);
		QString foldernamewithpath = _workContextDir+"\\meshes\\" + resourcename;
		compressionFileTo(foldernamewithpath,filenamewithpath);
	}

	osg::ref_ptr<CoreBase::Map> DataManager::importResourceJc(const QString& resource)
	{
		QFileInfo fileinfo(resource);
		decompressionSceneSources(resource);
		loadResource(fileinfo.fileName(),false);
		return _allResourceMap.value(fileinfo.fileName());
	}

	void DataManager::removeResourceFromMap(const QString& resource)
	{
		getCurrentMap()->removeResource(resource);
		_allResourceMap.remove(resource);
	}

	osg::ref_ptr<CoreBase::Map> DataManager::getResourceMap(const QString& resourcename)
	{
		QMap<QString,osg::ref_ptr<CoreBase::Map>>::Iterator iter = _allResourceMap.find(resourcename);
		if(iter!=_allResourceMap.end())
			return iter.value();
		return osg::ref_ptr<CoreBase::Map>(NULL);
	}

	bool DataManager::haveResourceFileInContext(const QString& jcname)
	{
		QString filename = jcname.mid(0,jcname.lastIndexOf('.'));
		QString pathstr = _workContextDir+"\\meshes\\" + jcname + "\\maps\\" + filename + ".jcyj";
		return QFile::exists(pathstr);
	}

	void DataManager::saveAllResourceToFile()
	{
		QMap<QString,osg::ref_ptr<CoreBase::Map>>::Iterator iter = _allResourceMap.begin();
		for(;iter!=_allResourceMap.end();++iter)
		{
			QString mapfilewithpath = _workContextDir+"\\meshes\\" + iter.key()+"\\maps\\";
			QString filename = iter.key().mid(0,iter.key().lastIndexOf('.'));
			_mapXMLRW->saveXMLFile(mapfilewithpath+filename+".jcyj",iter.value().get());
		}
	}

	QVector<osg::ref_ptr<CoreBase::ActorBase>> DataManager::importModelFileToResourceMap(const QStringList& list,const QString& jcfile,bool covered)
	{
		QString jcfilewithpath = _workContextDir+"\\meshes\\" + jcfile+"\\meshes";
		copyFileToFolder(list,jcfilewithpath,covered);
		CoreBase::Map* resourcemap = getResourceMap(jcfile);
		QFileInfo fileinfo;
		QVector<osg::ref_ptr<CoreBase::ActorBase>> returnvector;
		for(int i=0;i<list.size();++i)
		{
			fileinfo.setFile(list.at(i));
			QString filename = fileinfo.fileName();
			QString completebasename = fileinfo.completeBaseName();
			//create device
			osg::ref_ptr<CoreBase::ActorBase> devactor = _actorFactory->createActorByDataType(CLASS_DEVICE_GROUP);
			devactor->setName(completebasename);
			osg::ref_ptr<CoreBase::ActorBase> meshactor = _actorFactory->createActorByDataType(CLASS_MODEL);
			meshactor->setName(filename);
			meshactor->getProperty(ACTOR_PROPERYT_MESH)->fromString("\\meshes\\"+filename);
			dynamic_cast<DeviceActor*>(devactor.get())->addDrawableActor(meshactor.get());
			resourcemap->addActor(*devactor.get());
			returnvector.push_back(devactor);
			//add profession property class
			osg::ref_ptr<CoreBase::ActorBase> professionactor = _actorFactory->createActorByDataType(CLASS_PROFESSIONPROPERTY);
			professionactor->getProperty("Owner Id")->fromString(devactor->getId());
			resourcemap->addActor(*professionactor.get());
		}
		return returnvector;
	}

	void DataManager::removeModelFromResourceMap(CoreBase::ActorBase* actor,const QString& jcfile)
	{
		QString jcfilewithpath = _workContextDir+"\\meshes\\" + jcfile+"\\meshes";
		QString modelfilename = dynamic_cast<DeviceActor*>(actor)->getAllMeshDrawableActor().at(0)->getName();
		QFile::remove(jcfilewithpath+"\\"+modelfilename);
		osg::ref_ptr<CoreBase::Map> rm = getResourceMap(jcfile);
		rm->removeActor(*actor);
	}

	void DataManager::replaceResourceModel(const QString& modelfile,CoreBase::ActorBase* actor,const QString& jcfile)
	{
		QString jcfilewithpath = _workContextDir+"\\meshes\\" + jcfile+"\\meshes";
		QString modelfilename = dynamic_cast<DeviceActor*>(actor)->getAllMeshDrawableActor().at(0)->getName();
		QFile::remove(jcfilewithpath+"\\"+modelfilename);
		QString fullfilepath = jcfilewithpath+"\\"+modelfilename;
		QFile::copy(modelfile,fullfilepath);
		//update scene
		QMap<QString,osg::ref_ptr<CoreBase::ActorBase>> allactors = _currentMap->getAllActors();
		QMap<QString,osg::ref_ptr<CoreBase::ActorBase>>::iterator iter = allactors.begin();
		for(;iter!=allactors.end();++iter)
		{
			if(iter.value()->isInstanceOf(CLASS_DEVICE) && iter.value()->getName() == actor->getName())
			{
				CoreBase::Drawable* parent = iter.value()->getDrawable()->getParent();
				parent->removeChild(iter.value()->getDrawable());
				CoreBase::ResourceLoader::GetInstance().removeNodeFromCache(fullfilepath);
				parent->addChild(iter.value()->getDrawable());
			}			
		}
	}

	void DataManager::onResourceMapLoadEnd(CoreBase::Map* map)
	{
		QMap<QString,osg::ref_ptr<CoreBase::ActorBase>> allactors = map->getAllActors();
		QMap<QString,osg::ref_ptr<CoreBase::ActorBase>>::Iterator iter = allactors.begin();
		for(;iter!=allactors.end();++iter)
		{
			iter.value()->onMapLoadEnd(map);
		}
	}

	osg::ref_ptr<CoreBase::ActorBase> DataManager::getResourceActorByName(const QString& actorname)
	{
		QMap<QString,CoreBase::ActorBase*>::iterator findval = _deviceNameToResourceActor.find(actorname);
		if(findval!=_deviceNameToResourceActor.end())
		{
			return findval.value();
		}
		QMap<QString,osg::ref_ptr<CoreBase::Map>>::iterator iter = _allResourceMap.begin();
		for(;iter!=_allResourceMap.end();++iter)
		{
			if(actorname.startsWith(iter.key()))
			{
				CoreBase::ActorBase* getactor = iter.value()->getActorByName(actorname);
				if(getactor!=NULL)
				{
					_deviceNameToResourceActor.insert(actorname,getactor);
					return getactor;
				}
			}
		}
		return NULL;
	}

	osg::ref_ptr<CoreBase::ActorBase> DataManager::getResourceActorByType(int type,int subtype)
	{
		QMap<int,QMap<int,CoreBase::ActorBase*>>::iterator findval = _deviceTypeToResourceActor.find(type);
		if(findval!=_deviceTypeToResourceActor.end())
		{
			//QMap<int,CoreBase::ActorBase*>::Iterator citer = findval.value().find(subtype);
			//if(citer!=findval.value().end())
			//	return citer.value();
			return findval.value().begin().value();
		}
		QMap<QString,osg::ref_ptr<CoreBase::Map>>::iterator iter = _allResourceMap.begin();
		for(;iter!=_allResourceMap.end();iter++)
		{
			QMap<QString,osg::ref_ptr<CoreBase::ActorBase>> allactor = iter.value()->getAllActors();
			QMap<QString,osg::ref_ptr<CoreBase::ActorBase>>::iterator actoriter = allactor.begin();
			for(;actoriter!=allactor.end();++actoriter)
			{
				if(actoriter.value()->isInstanceOf(CLASS_DEVICE))
				{
					DeviceActor* actor = dynamic_cast<DeviceActor*>(actoriter.value().get());
					if(actor->getDeviceType() == type /*&& actor->getSubType() == subtype*/)
					{
						//if(findval!=_deviceTypeToResourceActor.end())
						//	findval.value().insert(subtype,actoriter.value());
						//else
						//{
							QMap<int,CoreBase::ActorBase*> newmap;
							newmap.insert(subtype,actoriter.value());
							_deviceTypeToResourceActor.insert(type,newmap);
						//}
						return actoriter.value().get();
					}
				}
			}
		}
		return NULL;
	}

	osg::ref_ptr<osg::StateSet> DataManager::getPublicStateSetByDrawableName(const QString& name)
	{
		if(_drawableNameToStateSet.contains(name))
		{
			return _drawableNameToStateSet.value(name);
		}
		osg::ref_ptr<osg::StateSet> ss = new osg::StateSet;
		_drawableNameToStateSet.insert(name,ss);
		return ss.get();
	}

	bool DataManager::containsPublicStateSetByDrawableName(const QString& name)
	{
		if(_drawableNameToStateSet.contains(name))
			return true;
		else
			return false;
	}

	osg::ref_ptr<osg::StateSet> DataManager::getPublicStateSetWithNoProgram()
	{
		if(!containsPublicStateSetByDrawableName("with no program stateset"))
		{
			osg::StateSet* ss = getPublicStateSetByDrawableName("with no program stateset").get();
			osg::ref_ptr<osg::Program> program = new osg::Program;
			program->setName("null program");
			ss->setAttributeAndModes( program.get(), osg::StateAttribute::ON|osg::StateAttribute::PROTECTED);
		}
		return getPublicStateSetByDrawableName("with no program stateset");
	}
}